package com.sailors.common.task.provider.infra.design.common.util;

import lombok.extern.slf4j.Slf4j;

import java.time.Instant;
import java.time.LocalDateTime;
import java.time.ZoneId;
import java.time.ZoneOffset;
import java.time.format.DateTimeFormatter;
import java.util.Calendar;
import java.util.Date;
import java.util.GregorianCalendar;

@Slf4j
public class DateTimeUtils {
    private static final ZoneOffset ZONE_OFFSET = ZoneOffset.systemDefault().getRules().getOffset(Instant.now());

    public static LocalDateTime timestampToDateTime(long timestamp) {
        return LocalDateTime.ofInstant(Instant.ofEpochMilli(timestamp), ZoneId.systemDefault());
    }

    public static Long dateTimeToSeconds(LocalDateTime dateTime) {
        if (dateTime == null) {
            return 0L;
        }
        return dateTime.toEpochSecond(ZONE_OFFSET);
    }

    public static Long dateTimeToMillis(LocalDateTime dateTime) {
        if (dateTime == null) {
            return 0L;
        }
        return dateTime.toInstant(ZONE_OFFSET).toEpochMilli();
    }

    private static final DateTimeFormatter SIMPLE_DATE_FORMAT = DateTimeFormatter.ofPattern("yyyy-MM-dd hh:mm:ss");
    private static final DateTimeFormatter SIMPLE_DATE_FORMAT2 = DateTimeFormatter.ofPattern("yyyy/MM/dd");

    public static String timestampToDateString(Long timestamp) {
        return timestampToString(timestamp, SIMPLE_DATE_FORMAT);
    }

    public static String timestampToDateString2(Long timestamp) {
        return timestampToString(timestamp, SIMPLE_DATE_FORMAT2);
    }

    public static String timestampToDateString3(Long timestamp, ZoneId zoneId) {
        if (timestamp == null) {
            return "";
        }
        log.info("timestamp：{}, zoneId:{}", timestamp, zoneId);
        return LocalDateTime.ofInstant(Instant.ofEpochMilli(timestamp), zoneId).format(SIMPLE_DATE_FORMAT2);
    }


    public static String dateToDateString1(LocalDateTime date, ZoneId zoneId) {
        if (date == null) {
            return "";
        }
        log.info("date：{}, zoneId:{}", date, zoneId);

        return date.atZone(zoneId).format(SIMPLE_DATE_FORMAT2);
    }

    public static String dateToDateString3(Date date, ZoneId zoneId) {
        if (date == null) {
            return "";
        }
        log.info("date：{}, zoneId:{}", date, zoneId);
        return LocalDateTime.ofInstant(Instant.ofEpochMilli(date.getTime()), zoneId).format(SIMPLE_DATE_FORMAT2);
    }

    public static String dateToYyyy_MM_dd(Date date, ZoneId zoneId) {
        if (date == null) {
            return "";
        }
        log.info("date：{}, zoneId:{}", date, zoneId);
        return LocalDateTime.ofInstant(Instant.ofEpochMilli(date.getTime()), zoneId).format(SIMPLE_DATE_FORMAT2);
    }

    public static String dateToDateString4(Date date, ZoneId zoneId) {
        if (date == null) {
            return "";
        }
        log.info("date：{}, zoneId:{}", date, zoneId);
        return LocalDateTime.ofInstant(Instant.ofEpochMilli(date.getTime()), zoneId).format(SIMPLE_DATE_FORMAT);
    }

    public static String dateTimeToString(Date date, ZoneId zoneId) {
        if (date == null) {
            return "";
        }
        log.info("date：{}, zoneId:{}", date, zoneId);
        return LocalDateTime.ofInstant(Instant.ofEpochMilli(date.getTime()), zoneId).format(SIMPLE_DATE_TIME_FORMAT);
    }
    private static final DateTimeFormatter SIMPLE_DATE_TIME_FORMAT = DateTimeFormatter.ofPattern("yyyy-MM-dd HH:mm:ss");
    private static final DateTimeFormatter SIMPLE_DATE_TIME_FORMAT2 = DateTimeFormatter.ofPattern("yyyy/MM/dd HH:mm:ss");
    private static final DateTimeFormatter SIMPLE_DATE_TIME_FORMAT3 = DateTimeFormatter.ofPattern("yyyy/MM/dd");
    private static final DateTimeFormatter SIMPLE_DATE_TIME_FORMAT4 = DateTimeFormatter.ofPattern("HH:mm:ss");

    public static String timestampToDateTimeString(Long timestamp) {
        return timestampToString(timestamp, SIMPLE_DATE_TIME_FORMAT);
    }

    public static String timestampToDateTimeString2(Long timestamp) {
        return timestampToString(timestamp, SIMPLE_DATE_TIME_FORMAT2);
    }

    public static String timestampToDateTimeString3(Long timestamp) {
        return timestampToString(timestamp, SIMPLE_DATE_TIME_FORMAT3);
    }

    public static String timestampToDateTimeString4(Long timestamp) {
        return timestampToString(timestamp, SIMPLE_DATE_TIME_FORMAT4);
    }

    public static String timestampToString(Long timestamp, DateTimeFormatter formatter) {
        if (timestamp == null) {
            return "";
        }
        return timestampToDateTime(timestamp).format(formatter);
    }

    public static Date getDayBeginService() {
        Calendar cal = new GregorianCalendar();
        cal.set(Calendar.HOUR_OF_DAY, 0);
        cal.set(Calendar.MINUTE, 0);
        cal.set(Calendar.SECOND, 0);
        cal.set(Calendar.MILLISECOND, 0);
        return cal.getTime();
    }

    public static Date getDayEndService() {
        Calendar cal = new GregorianCalendar();
        cal.set(Calendar.HOUR_OF_DAY, 23);
        cal.set(Calendar.MINUTE, 59);
        cal.set(Calendar.SECOND, 59);
        return cal.getTime();
    }

    public static Date getDayBeginService(Date date) {
        Calendar cal = new GregorianCalendar();
        cal.setTime(date);
        cal.set(Calendar.HOUR_OF_DAY, 0);
        cal.set(Calendar.MINUTE, 0);
        cal.set(Calendar.SECOND, 0);
        cal.set(Calendar.MILLISECOND, 0);
        return cal.getTime();
    }

    public static Date getDayEndService(Date date) {
        Calendar cal = new GregorianCalendar();
        cal.setTime(date);
        cal.set(Calendar.HOUR_OF_DAY, 23);
        cal.set(Calendar.MINUTE, 59);
        cal.set(Calendar.SECOND, 59);
        return cal.getTime();
    }
}
